package com.zh.config.fragment

import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
import android.net.http.SslError
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.webkit.JavascriptInterface
import android.webkit.SslErrorHandler
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.widget.EditText
import androidx.core.widget.NestedScrollView
import com.blankj.utilcode.util.LogUtils
import com.zh.common.base.BaseFragment
import com.zh.common.databinding.FragmentWebBinding
import com.zh.common.ktx.gotoAct
import com.zh.common.utils.EmptyUtils
import com.zh.common.view.web.IWebView
import com.zh.config.ZjConfig
import com.zh.config.utils.LinkCheckIsDown
import java.util.regex.Matcher
import java.util.regex.Pattern

/**
 * 解决NestedScrollView嵌套WebView问题
 * WebView默认设置一些属性
 * 1、如果有播放视频，所在的Activity必须设置以下属性
 * android:configChanges="orientation|screenSize|keyboardHidden"
 * android:launchMode="singleTask"
 * android:theme="@style/Theme.AppCompat.Light.NoActionBar"
 * android:windowSoftInputMode="stateVisible|adjustResize"
 * 2、Scrollview嵌入WebView，解决在WebView中点击链接页面会向上滑动一下
 * android:descendantFocusability="blocksDescendants"
 */
class WebFragment : BaseFragment<FragmentWebBinding>() {

    private val method = "android"
    private val imageUrls = mutableListOf<String?>()
    var etContent: EditText? = null

    override fun initView(savedInstanceState: Bundle?) {
        viewBinding.apply {
            webView.activity = activity
            webView.addJavascriptInterface(IJavascriptInterface(imageUrls), method)
            webView.setMyWebViewClient(object : IWebView.MyWebViewClient {
                override fun onPageFinished(view: WebView, url: String) {
                    etContent?.setText(url)
                    webView.postDelayed({
                        setWebImageClick(view, method)
                    }, 500)
                }

                override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                    etContent?.setText(url)
                }

                override fun shouldOverrideUrlLoading(
                    view: WebView?,
                    request: WebResourceRequest?
                ): Boolean {
                    Log.e("webView", "shouldOverrideUrlLoading->${request?.url}")
                    if (!arrayOf(
                            "http", "https", "file", "chrome", "data", "javascript", "about"
                        ).contains(request?.url?.scheme)
                    ) {
                        Log.e("webView", "拦截了url->${request?.url}")
                        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(request?.url?.toString()))
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        try {
                            context?.startActivity(intent)
                            return true
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                        return false
                    }
                    if (LinkCheckIsDown.isDownloadLink(request?.url.toString())) {
                        Log.e("webView", "拦截了url->${request?.url}")
                        // TODO: 下载文件逻辑
                        return true
                    }
                    return false
                }

                override fun onReceivedSslError(
                    view: WebView,
                    handler: SslErrorHandler,
                    error: SslError
                ) {

                }
            })
            webView.setDownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
                LogUtils.e(
                    "webView", "DownloadListener url->$url",
                    userAgent, contentDisposition, mimetype, contentLength
                )
                if (EmptyUtils.isNotEmpty(contentDisposition)) {
                    var filename =
                        contentDisposition.substring(contentDisposition.indexOf("filename=") + 9)
                    filename = filename.replace("\"".toRegex(), "")
                    // TODO: 下载文件逻辑
                }
            }
        }
    }

    // 创建一个 Intent 并尝试启动第三方应用
    private fun openUrlInThirdPartyApp(url: Uri?) {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url?.toString()))
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        try {
            context?.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun loadUrl(url: String) {
        viewBinding.webView.loadUrl(url)
    }

    fun loadUrl(url: String, scrollView: NestedScrollView) {
        viewBinding.webView.mScrollView = scrollView
        viewBinding.webView.loadUrl(url)
    }

    /**
     * 加载富文本
     */
    fun loadDataWithBaseURL(data: String) {
        loadData(data)
    }

    fun loadDataWithBaseURL(data: String, scrollView: NestedScrollView) {
        viewBinding.webView.mScrollView = scrollView
        loadData(data)
    }

    private fun loadData(data: String) {
        //得到图片
        imageUrls.clear()
        imageUrls.addAll(returnImageUrlsFromHtml(data))
        viewBinding.webView.let {
            val linkCss = "<head>" +
                    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\"> " +
                    "<style>html{padding:0px;} " +
                    "img{max-width:100% !important;height:auto;}" +
                    "video{max-width:100% !important;height:auto;background:#000;}" +
                    "div{max-width:100% !important;height:auto;}" +
                    "</style></head>"
            val html = "<html>$linkCss<body>$data</body></html>"
            it.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null)
        }
    }

    fun canGoBack() = viewBinding.webView.canGoBack()
    fun canGoForward() = viewBinding.webView.canGoForward()
    fun goBack() {
        viewBinding.webView.goBack()
    }

    fun goForward() {
        viewBinding.webView.goForward()
    }

    override fun onPause() {
        viewBinding.webView.onPause()
        super.onPause()
    }

    override fun onResume() {
        viewBinding.webView.onResume()
        super.onResume()
    }

    override fun onDestroy() {
        super.onDestroy()
        viewBinding.webView.destroy()
    }

    fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK && event?.action == KeyEvent.ACTION_DOWN) {
            val isLandscape =
                (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
            viewBinding.webView.apply {
                return if (isLandscape) {
                    needRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    true
                } else if (canGoBack()) {
                    goBack()
                    true
                } else {
                    requireActivity().finish()
                    false
                }
            }
        }
        return false
    }

    /**
     * 找到html中所有的图片url
     * @param htmlCode
     * @return
     */
    private fun returnImageUrlsFromHtml(htmlCode: String): MutableList<String?> {
        val imageSrcList = mutableListOf<String?>()
        val p = Pattern.compile(
            "<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\u000c>]+(\\.jpg|\\.bmp|\\.eps|\\.gif|\\.mif|\\.miff|\\.png|\\.tif|\\.tiff|\\.svg|\\.wmf|\\.jpe|\\.jpeg|\\.dib|\\.ico|\\.tga|\\.cut|\\.pic|\\b)\\b)[^>]*>",
            Pattern.CASE_INSENSITIVE
        )
        val m: Matcher = p.matcher(htmlCode)
        var quote: String? = null
        var src: String? = null
        while (m.find()) {
            quote = m.group(1)
            src = if (quote == null || quote.trim { it <= ' ' }.isEmpty()) m.group(2)
                .split("//s+".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray()[0] else m.group(2)
            imageSrcList.add(src)
        }
        return if (imageSrcList.size == 0) mutableListOf()
        else imageSrcList
    }

    inner class IJavascriptInterface {

        private var imageUrls: MutableList<String?> = mutableListOf()

        constructor()
        constructor(urls: MutableList<String?>) {
            imageUrls = urls
        }

        //java回调js代码，不要忘了@JavascriptInterface这个注解，不然点击事件不起作用
        @JavascriptInterface
        fun openImage(img: String, pos: Int) {
            val arrayList = ArrayList<String?>()
            for (item in imageUrls) {
                arrayList.add(item)
            }
            //实现自己的图片浏览页面
            gotoAct(ZjConfig.Routes.LOOK_BIG_IMAGE, true) {
                putStringArrayList("imageUrls", arrayList)
                putInt("pos", pos)
            }
        }
    }

    /**
     * 设置网页中图片的点击事件
     * 视频默认播放到0.1秒来当做封面图
     * @param view
     */
    private fun setWebImageClick(view: WebView, method: String) {
        val jsCode = "javascript:(function(){" +
                "var imgs=document.getElementsByTagName(\"img\");" +
                "for(var i=0;i<imgs.length;i++){" +
                "   imgs[i].pos = i;" +
                "   imgs[i].onclick=function(){" +
                "       window." + method + ".openImage(this.src,this.pos);" +
                "   }" +
                "}" +
                "var videos = document.getElementsByTagName('video');" +
                "for (var i = 0; i < videos.length; i++) {" +
                "var video = videos[i];" +
                "    (function(i) {" +
                "        video.currentTime = 0.1;" +
                "        video.addEventListener('seeked', function() {" +
                "            var canvas = document.createElement('canvas');" +
                "            canvas.width = video.videoWidth;" +
                "            canvas.height = video.videoHeight;" +
                "            canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);" +
                "            var dataURL = canvas.toDataURL('image/png');" +
                "            video.poster = dataURL;" +
                "            video.pause();" +
                "        });" +
                "    })(i);" +
                "   }" +
                "})()"
        view.loadUrl(jsCode)
    }
}